﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace Skywave.ComponentModel
{
    public class ExceptionReporter
    {
        public event EventHandler<ExceptionReporterTryCompletedEvenArgs> SendTryCompleted;
        private System.ComponentModel.BackgroundWorker backgroundWorkerSend;
        private bool isSent = false;
        private Exception sendEx;

        public ExceptionReporter(Exception ex, System.Net.Mail.SmtpClient sendingService)
        {
            backgroundWorkerSend = new System.ComponentModel.BackgroundWorker();
            _ExceptionToSend = ex;
            backgroundWorkerSend.DoWork += new DoWorkEventHandler(backgroundWorkerSend_DoWork);
            backgroundWorkerSend.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorkerSend_RunWorkerCompleted);
            _SendingService_Smtp = sendingService;
        }

        private Exception _ExceptionToSend;
        /// <summary>
        /// ExceptionToSend Property
        /// </summary>
        public Exception ExceptionToSend
        {
            get { return _ExceptionToSend; }
        }
        
        private System.Net.Mail.SmtpClient _SendingService_Smtp;
        /// <summary>
        /// SendingService_Smtp Property
        /// </summary>
        public System.Net.Mail.SmtpClient SendingService_Smtp
        {
            get { return _SendingService_Smtp; }
        }

        /// <summary>
        /// CustomSubject Property
        /// </summary>
        public string CustomSubject
        {
            get { return _CustomSubject; }
            set { _CustomSubject = value; }
        }
        private string _CustomSubject;

        /// <summary>
        /// CustomBody Property
        /// </summary>
        public string CustomBody
        {
            get { return _CustomBody; }
            set { _CustomBody = value; }
        }
        private string _CustomBody;

        private void backgroundWorkerSend_DoWork(object sender, DoWorkEventArgs e)
        {
            if (SendingService_Smtp == null)
                return;
            sendEx = null;
            isSent = false;
            System.Net.Mail.MailMessage mailMessage = new System.Net.Mail.MailMessage("masoftco@gmail.com", "mostafa_aghajani@yahoo.com");
            System.Reflection.Assembly assemblyEntry = System.Reflection.Assembly.GetEntryAssembly();
            System.Reflection.AssemblyName assemblyName = assemblyEntry.GetName();
            //
            mailMessage.Subject = "Error in " + assemblyName.FullName + " " + _CustomSubject;
            mailMessage.Body = "(" + assemblyName.Version.ToString() + ") Executable path:\n";
            if (!string.IsNullOrWhiteSpace(_CustomBody)) mailMessage.Body += _CustomBody + "\n";
            mailMessage.Body += assemblyName.CodeBase + "\n";
            mailMessage.Body += _ExceptionToSend.ToString();
            Exception innerEx = _ExceptionToSend.InnerException;
            int innerCount = 1;
            while (innerEx != null)
            {
                mailMessage.Body += "\n***********************\n\n";
                mailMessage.Body += "Inner Exception " + innerCount.ToString() + ":\n";
                mailMessage.Body += innerEx.ToString();
                innerEx = innerEx.InnerException;
                innerCount++;
            }
            try
            {
                SendingService_Smtp.Send(mailMessage);
                isSent = true;
            }
            catch (Exception ex)
            {
                isSent = false;
                sendEx = ex;
            }
        }

        private void backgroundWorkerSend_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (SendTryCompleted != null)
                SendTryCompleted(this, new ExceptionReporterTryCompletedEvenArgs(isSent, sendEx));
        }

        public void TrySend()
        {
            if (!backgroundWorkerSend.IsBusy)
                backgroundWorkerSend.RunWorkerAsync();
        }
    }
}
